home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Floppyshop 2
/
Floppyshop - 2.zip
/
Floppyshop - 2.iso
/
diskmags
/
0022-3.564
/
dmg-3323
/
protocol.gem
/
gfa
/
acc_400.gfa
(
.txt
)
< prev
next >
Wrap
GFA-BASIC Atari
|
1987-04-21
|
10KB
|
326 lines
' ACC 400
' Accessoire possédant un menu déroulant GEM
' Ce menu déroulant sera géré par le programme principal
'
' Les équivalences issues du fichier ressource
LET menu1&=0 ! menu tree
LET desk400&=3 !TITLE in tree MENU1
LET files400&=4 !TITLE in tree MENU1
LET tests400&=5 !TITLE in tree MENU1
LET about400&=8 !STRING in tree MENU1
LET quit400&=18 !STRING in tree MENU1
LET hello400&=20 !STRING in tree MENU1
LET check400&=21 !STRING in tree MENU1
'
$m 10000 ! petite réservation
my_menu$=" ACC400/GFA" ! titre du menu de cet ACC
' Les définitions des alertes
alert1$="[1][ACC_400, Accessoire avec|un vrai menu GEM!|Compatible Protocole!][ OK ]"
alert2$="[1][J'espère que vous allez|utiliser le protocole|dans vos programmes!][Ah oui!]"
alert3$="[1][Pas d'application|acceptant mon menu...][Dommage!]"
alert4$="[1][Ressource introuvable|(ACC_400.RSC)][Bye bye]"
alerte_tub1$="[1][Tableau endommagé, |communication par le|Tube GEM impossible.][ OK ]"
alerte_tub3$="[1][Probléme en $5A0 |Communication par le|Tube GEM impossible][ OK ]"
'
' Préparons les buffers
DIM new_jar%(31) ! pour le Cookie-jar
DIM tab_tub&(13) ! pour le tableau Protocole
DIM messagebuf&(7) ! pour émettre et recevoir les messages
'
flag_check&=0 !check du menu déroulant
'
app_id&=APPL_INIT() ! je demande mon identificateur d'application
IF RSRC_LOAD("\ACC_400.RSC")=0
~FORM_ALERT(1,alert4$)
END ! dur avec un ACC mais enfin...
ENDIF
~RSRC_GADDR(0,0,menu_ptr%) ! cherche adresse de mon menu
~MENU_REGISTER(app_id&,my_menu$) ! place mon nom dans le menu
' Mise en place du détournement de reset (Cookie-Jar STF)
@put_reset ! deux routines à utiliser à chaque fois,
@init_tube_acc ! et donc à mettre en bibliothéque
'
' Et nous commençons la grande attente !
DO
~EVNT_MESAG(VARPTR(messagebuf&(0))) ! attente des messages...
SELECT messagebuf&(0)
CASE 40 ! ouverture de l'accessoire
@open_acc ! allons le gérer
CASE 300 ! demande si compatible 300
@send_message(messagebuf&(1),301) ! je répond non (301)
CASE 400 ! demande si compatible 400
@send_message(messagebuf&(1),401) ! je répond non (401)
CASE 500 ! demande si compatible 500
@send_message(messagebuf&(1),501) ! je répond non (501)
ENDSELECT
LOOP
'
' Ouverture de l'accessoire. Recherche et vérification du tableau
' des APP_ID à cause d'une destruction toujours possible
> PROCEDURE open_acc
LOCAL action&
@find_apid
IF a0%<>0
maxi&=DPEEK(a0%+4)
a0%=a0%+4 !saute l'en-tête
' Recherche d'un correspondant
REPEAT
DEC maxi& !compte un APP_ID
a0%=a0%+2
IF DPEEK(a0%)=&HFFFF OR maxi&=0
~FORM_ALERT(1,alert3$) ! personne ne répond
ELSE
IF DPEEK(a0%)<>app_id& ! si ce n'est pas le notre
' Message pour ce correspondant potentiel
@send_message(DPEEK(a0%),400)
action&=EVNT_MULTI(&X110000,0,0,0,0,0,0,0,0,0,0,0,0,0,VARPTR(messagebuf&(0)),500)
IF action&<>&X100000 AND messagebuf&(0)=403
' Notre menu est accepté, envoyons son adresse
prg_id&=messagebuf&(1)
messagebuf&(0)=406
messagebuf&(1)=app_id&
messagebuf&(2)=0
LPOKE VARPTR(messagebuf&(3)),menu_ptr%
messagebuf&(5)=0
messagebuf&(6)=0
messagebuf&(7)=0
~APPL_WRITE(prg_id&,16,VARPTR(messagebuf&(0)))
' Puis attente de confirmation
~EVNT_MESAG(VARPTR(messagebuf&(0)))
SELECT messagebuf&(0)
CASE 405
@main !confirmation, menu actif->allons le gérer
maxi&=0 ! pour forcer la sortie
ENDSELECT ! sinon bye bye...
ENDIF
ENDIF
ENDIF
UNTIL DPEEK(a0%)=&HFFFF OR maxi&=0
ENDIF
RETURN
'
' Routine de gestion de notre menu déroulant à l'aide
' des messages en provenance du programme principal.
> PROCEDURE main
~FORM_ALERT(1,alert1$) ! publicité
flag_quitter!=FALSE
REPEAT
~EVNT_MESAG(VARPTR(messagebuf&(0)))
SELECT messagebuf&(0)
CASE 407
@gere_menu
IF flag_quitter!=TRUE
@send_message(prg_id&,408)
ENDIF
CASE 409 ! le prg retire mon menu
flag_quitter!=TRUE
ENDSELECT
UNTIL flag_quitter!=TRUE
RETURN
'
' Gestion du menu déroulant. Classique, bien que les messages
' viennent du PRG et non pas directement du GEM!
> PROCEDURE gere_menu
SELECT messagebuf&(4)
CASE about400&
~FORM_ALERT(1,alert1$)
CASE quit400&
flag_quitter!=TRUE
CASE hello400&
~FORM_ALERT(1,alert2$)
CASE check400&
flag_check&=BCHG(flag_check&,0)
~MENU_ICHECK(menu_ptr%,check400&,flag_check&)
ENDSELECT
~MENU_TNORMAL(menu_ptr%,messagebuf&(3),1)
RETURN
'
' Les procédures suivantes sont simplement à merger.
' Elles sont disponibles dans le dossier Biblio.
> PROCEDURE init_tube_acc
'
' Procédure d'initialisation pour accessoire
' Fichier ACC_INIT.LST
'
cookie4&=0 ! ne pas écraser
init_tub0:
cookie1%=CVL("_TUB") ! cookie recherché
cookie2%=VARPTR(new_jar%(0)) !
cookie3%=VARPTR(tab_tub&(0))
@cookie_jar
'
IF cookie2%<>0
IF cookie3%=VARPTR(tab_tub&(0)) ! si c'est ma liste
tab_tub&(0)=CVI("PR") ! je met son en-tête
tab_tub&(1)=CVI("OT")
tab_tub&(2)=10 ! le nbd d'app_id quelle peut contenir
tab_tub&(3)=app_id& ! mon APP_ID
tab_tub&(4)=-1 ! et la marque de fin
ELSE
' Vérifions le tableau Protocole en place...
IF LPEEK(cookie3%)<>CVL("PROT")
cookie4&=1 ! tableau invalide, nous
GOTO init_tub0 ! allons l'écraser...
ELSE
' Parcourons le tableau en place pour placer
' notre APP_ID et clore par &HFFFF
maxi&=DPEEK(cookie3%+4) ! nbr maxi d'app_id autorisés
cookie3%=cookie3%+6 ! saute l'en-tête
REPEAT
' Nous prévoyons le cas d'ACC lancés par Multidesk
' qui améne à avoir plusieurs fois le même APP_ID:
' Si nous y trouvons déja le notre -> bye bye!!!
EXIT IF DPEEK(cookie3%)=app_id&
IF DPEEK(cookie3%)=&HFFFF ! fin de la liste ?
DPOKE cookie3%,app_id& ! donc met mon APPID
DPOKE cookie3%+2,&HFFFF ! et l'indication de fin
ELSE
cookie3%=cookie3%+2 ! sinon passe à l'app_id
DEC maxi& ! suivant, et le compte
ENDIF
UNTIL DPEEK(cookie3%)=app_id& OR maxi&=0
ENDIF
ENDIF
ENDIF
RETURN
> PROCEDURE send_message(dest&,num&)
'
' Pour envoyer un message à une autre application
' Fichier SEND_MES.LST
'
messagebuf&(0)=num& !numéro du message
messagebuf&(1)=app_id& !mon identificateur d'application
messagebuf&(3)=0 !et tout le reste à 0
messagebuf&(4)=0
messagebuf&(5)=0
messagebuf&(6)=0
messagebuf&(7)=0
~APPL_WRITE(dest&,16,VARPTR(messagebuf&(0)))
RETURN
> PROCEDURE find_apid
'
' Recherche de la liste des APP_ID et retour de son
' adresse dans la variable a0%
' C'est une procédure commune aux ACCs et aux PRGs
' Fichier TUBEFIND.LST
'
cookie1%=CVL("_TUB")
cookie2%=0
cookie3%=0
cookie4&=0
@cookie_jar
'
IF cookie2%=0 OR cookie3%=0
~FORM_ALERT(1,alerte_tub3$)
a0%=0
ELSE
IF LPEEK(cookie3%)<>CVL("PROT")
~FORM_ALERT(1,alerte_tub1$)
a0%=0
ELSE
a0%=cookie3%
ENDIF
ENDIF
RETURN
> PROCEDURE cookie_jar
'
' Procédure permettant de lire et/ou d'écrire dans le Cookie-Jar.
' Par simplification, il s'agit de la même routine pour ACC et PRG
' alors qu'il aurait été possible d'en faire des différentes.
' Fichier COOKIJAR.LST
'
LOCAL temp%,x%,cmp%
cookie_jar0:
temp%=LPEEK(&H5A0) !cherche adresse cookie-jar
' S'il n'y a pas de boite, nous plaçons la notre
IF temp%=0
IF cookie2%<>0 ! si nous avons une boite à mettre...
SLPOKE &H5A0,cookie2% ! adresse de celle-ci
IF cookie1%<>0 ! si nous avons un cookie...
LPOKE cookie2%,cookie1%
LPOKE cookie2%+4,cookie3%
LPOKE cookie2%+8,0
LPOKE cookie2%+12,16
ENDIF
ENDIF
ELSE ! Il y a un Cookie-Jar
IF cookie1%<>0 ! si nous devons chercher un gateaux
cmp%=0 ! init. compteur de Cookie
REPEAT
x%=LPEEK(temp%) ! préléve l'identif. d'un cookie
temp%=temp%+8 ! avance sur le suivant
INC cmp% ! et compte ce cookie
UNTIL x%=0 OR x%=cookie1%
temp%=temp%-4 !reculons sur l'info. de ce cookie
' Si nous avons trouvé notre cookie1
IF x%=cookie1%
IF cookie4&=0 ! si nous devons juste noter l'information,
cookie3%=LPEEK(temp%) ! nous la notons et bye bye...
ELSE
LPOKE temp%,cookie3% ! sinon nous la forçons
ENDIF
ELSE
' Nous avons trouvé la fin de la boite, nous mettons
' notre cookie, s'il reste de la place...
IF LPEEK(temps%)=0 ! précaution si nbr de slot nul,
SLPOKE &H5A0,0 ! la boite est mauvaise...
GOTO cookie_jar0
ENDIF
IF cookie3%<>0 ! si nous avons quelque chose à mettre
IF cmp%<LPEEK(temp%) ! s'il reste de la place...
LPOKE (temp%+4),0 ! flag de fin
LPOKE (temp%+8),LPEEK(temp%) ! transfert le nbr d'emplacement
LPOKE (temp%-4),cookie1% ! place l'identif. de notre cookie
LPOKE (temp%),cookie3% ! et sa valeur d'info
ELSE
' Il n'y a pas assez de place: plaçons une plus grosse boite
IF cmp%<16 AND cookie2%<>0 ! si nous pouvons...
temp%=LPEEK(&H5A0) ! adr ancien cookie-jar
SLPOKE &H5A0,cookie2% ! note adr du nouveau
WHILE LPEEK(temp%)<>0
LPOKE cookie2%,LPEEK(temp%)
LPOKE cookie2%+4,LPEEK(temp%+4)
temp%=temp%+8
cookie2%=cookie2%+8
WEND
LPOKE (cookie2%),cookie1%
LPOKE (cookie2%+4),cookie3%
LPOKE (cookie2%+8),0
LPOKE (cookie2%+12),16
ELSE
' Boite pas assez grosse ou pas de boite à mettre ...
cookie3%=0
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
cookie2%=LPEEK(&H5A0)
RETURN
> PROCEDURE put_reset
'
' Procédure pour détourner le reset et y placer une routine
' effaçant le contenu de $5A0 (cas d'un Cookie-Jar de STF)
' Fichier RESET.LST
'
RESTORE asm_data
DO
READ code$
EXIT IF code$="FIN"
code$="&H"+code$
code%=VAL(code$)
asm$=asm$+MKI$(code%)
LOOP
asm%=VARPTR(asm$)
LPOKE asm%+8,LPEEK(&H426) ! prend ancien magique
LPOKE asm%+18,LPEEK(&H42A) ! prend ancienne routine
SLPOKE &H426,&H31415926 ! magique reset
SLPOKE &H42A,asm%
RETURN
asm_data:
DATA 42B9,0000,05A0
DATA 23FC,0000,0000,0000,0426
DATA 23FC,0000,0000,0000,042A
DATA 4ED6,FIN